#include <apr_network_io.h>
#include "mpi.h"
#include "oom.h"
/** \file util.c
 */
apr_status_t apr_socket_gets(char *str, int len, apr_socket_t *thesocket)
{
	apr_status_t rv = APR_SUCCESS;
	apr_size_t nbytes;
	const char *str_start = str;
	char *final = str + len + 1;
	
	if (len <= 1)
	{
		return APR_SUCCESS;
	}
	
	while (str < final)
	{
		nbytes = 1;
		rv = apr_socket_recv(thesocket, str, &nbytes);
		if (rv != APR_SUCCESS)
		{
			break;
		}
		if (*str == '\n')
		{
			++str;
			break;
		}
		++str;
	}
	
	/* store a terminating null character and return success
	  if we have stored any characters */

	if (str > str_start)
	{
		*str = '\0';
		return APR_SUCCESS;
	}
	return rv;
}

apr_status_t apr_socket_puts(const char *str, apr_socket_t *thesocket)
{
	apr_status_t status;
	apr_size_t nbytes = strlen(str);

	do
	{
		apr_size_t amt = nbytes;
		
		status = apr_socket_send(thesocket, str, &amt);
		str = (char *)str + amt;
		nbytes -= amt;
	}
	while (status == APR_SUCCESS && nbytes > 0);
	
	return status;
}

apr_status_t apr_socket_recv_full(apr_socket_t *thesocket, void *buf,
	apr_size_t nbytes, apr_size_t *bytes_received)
{
	apr_status_t status;

	*bytes_received = 0;
	do
	{
		apr_size_t amt = nbytes;
		
		status = apr_socket_recv(thesocket, buf, &amt);
		buf = (char *)buf + amt;
		nbytes -= amt;
		*bytes_received += amt;
	}
	while (status == APR_SUCCESS && nbytes > 0);
	
	return status;
}

apr_status_t apr_socket_send_full(apr_socket_t *thesocket, void *buf,
	apr_size_t nbytes, apr_size_t *bytes_sent)
{
	apr_status_t status;

	*bytes_sent = 0;
	do
	{
		apr_size_t amt = nbytes;
		
		status = apr_socket_send(thesocket, buf, &amt);
		buf = (char *)buf + amt;
		nbytes -= amt;
		*bytes_sent += amt;
	}
	while (status == APR_SUCCESS && nbytes > 0);
	
	return status;
}

void set_status_empty(MPI_Status *status)
{
	if (status == MPI_STATUS_IGNORE) return;
	status->MPI_SOURCE = MPI_ANY_SOURCE;
	status->MPI_TAG = MPI_ANY_TAG;
	status->bytes_recvd = 0;
}

void set_status_from_request(MPI_Status *status, Request *request)
{
	if (status == MPI_STATUS_IGNORE) return;
	status->MPI_SOURCE = request->matched_env.source;
	status->MPI_TAG = request->matched_env.tag;
	status->bytes_recvd = request->num_bytes;
}
